import 'package:fluttertoast/fluttertoast.dart';
import 'package:macnov/form/budget.dart';
import 'package:macnov/models/budget.dart';
import 'package:macnov/models/budget_member.dart';
import 'package:macnov/models/company_user.dart';
import 'package:macnov/utils/Api.dart';
import 'package:macnov/utils/constant.dart';
import 'package:mobx/mobx.dart';

// Include generated file
part 'budget.g.dart';

// This is the class used by rest of your codebase
class Budget = _Budget with _$Budget;

// The store-class
abstract class _Budget with Store {
  @observable
  List budgets = [];
  @observable
  List filterBudgets = [];

  @observable
  bool loading = false;

  @observable
  BudgetMember budgetMember;

  @observable
  List allUsers = [];

  @observable
  List memberUsers = [];

  @observable
  List ownerUsers = [];

  @observable
  CompanyUser ownerUser;

  @observable
  BudgetAddForm budgetAddForm = BudgetAddForm();

  @observable
  BudgetAddForm budgetEditForm = BudgetAddForm();

  bool findUser(List list, CompanyUser target) {
    return list.indexWhere((u) => u.mid == target.mid) != -1;
  }

  bool hasOwner() {
    return ownerUser != null && ownerUser.selected == true;
  }

  @action
  Future selectOwnerUser(CompanyUser selectUser) async {
    selectUser.selected = !selectUser.selected;
    ownerUser = selectUser;
    ownerUsers = ownerUsers.toList(growable: true);
    if (selectUser.selected == true) {
      ownerUsers.forEach((u) {
        if (u.mid != selectUser.mid) {
          u.selected = false;
        }
      });
    }

    List memList = [];

    List unselectOwners = ownerUsers.where((u) => u.selected == false).toList();

    allUsers.forEach((u) {
      if (!findUser(ownerUsers, u)) {
        memList.add(u);
      }
    });
    memList.addAll(unselectOwners);

    memberUsers = copyList(memList);
  }

  @action
  Future selectMemberUser(CompanyUser selectUser) async {
    selectUser.selected = !selectUser.selected;

    memberUsers = memberUsers.toList(growable: true);

    List ownerList = [];

    List selectMembers = memberUsers.where((u) => u.selected == true).toList();
    allUsers.forEach((user) {
      if (findUser(selectMembers, user) == false) {
        ownerList.add(user);
      }
    });

    if (hasOwner()) {
      ownerList.forEach((u) {
        if (u.mid == ownerUser.mid) {
          u.selected = true;
        } else {
          u.selected = false;
        }
      });
      print('ownerList ${ownerList.length}');
    }
    ownerUsers = copyList(ownerList);
  }

  List<dynamic> copyList(copyList) {
    List list = [];
    copyList.forEach((user) {
      CompanyUser companyUser = new CompanyUser();
      companyUser.first = user.first;
      companyUser.last = user.last;
      companyUser.mid = user.mid;
      companyUser.selected = user.selected;
      list.add(companyUser);
    });
    return list;
  }

  @action
  Future loadCompanyUsers() async {
    var list = await Api.getCompanyUsers();
    if (list != null) {
      allUsers = list.map((json) => CompanyUser.fromJson(json)).toList();
      ownerUsers = copyList(allUsers);
      memberUsers = copyList(allUsers);
    }
  }

  @action
  Future loadBudgets() async {
    var list = await Api.getCompanyActiveBudgets();
    if (list != null) {
      budgets = list.map((json) => BudgetModel.fromJson(json)).toList();
      filterBudgets = budgets;
    }
  }

  Future loadEmployeeBudgets() async {
    var list = await Api.getMyActiveMemberBudgets();
    if (list != null) {
      budgets = list.map((json) => BudgetModel.fromJson(json)).toList();
      filterBudgets = budgets;
    }
  }

  filterBudget(budget, keyword) {
    String budgetLowerCase = budget.name.toLowerCase();
    String keywordLowerCase = keyword.toString().toLowerCase();
    return budgetLowerCase.indexOf(keywordLowerCase) != -1;
  }

  @computed
  String get showOwnerStr {
    if (ownerUser != null && ownerUser.selected == true) {
      return ownerUser.first;
    }
    return ownerUsers.fold('', (a, b) => a + b.first + '');
  }

  @computed
  String get showMemberStr {
    List selectUsers =
        memberUsers.where((user) => user.selected == true).toList();
    if (selectUsers.length > 1) {
      CompanyUser selectUser = selectUsers.first;
      return selectUser.first  +',+'+
          (selectUsers.length - 1).toString();
    }
    return selectUsers.fold('', (a, b) => a + b.first  + '');
  }

  @action
  Future filter(String keyword) async {
    filterBudgets =
        budgets.where((budget) => filterBudget(budget, keyword)).toList();
  }

  @action
  Future loadBudgetMembers(String budgetId) async {
    var json = await Api.getBudgetPeopleCards(budgetId);
    budgetMember = BudgetMember.fromJson(json);
  }

  @action
  Future saveOwnerFormData() async {
    budgetAddForm.owners =
        ownerUsers.where((user) => user.selected == true).toList();
  }

  @action
  Future saveMemberFormData() async {
    budgetAddForm.members =
        memberUsers.where((user) => user.selected == true).toList();
  }

  @action
  Future createBudget(Map<String, dynamic> formData, OnVoidSuccess cb) async {
    var json = await Api.createBudget(formData);
    if (json != null) {
      String message = 'Add Successfully !';
      if (false == json['success']) {
        message = json['message'] ?? '';
      } else {
        cb();
      }
      Fluttertoast.showToast(
          msg: message,
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIos: 1,
          fontSize: 16.0);
    }
  }

  @action
  Future deleteBudget(String budgetId, OnVoidSuccess cb) async {
    Map<String, dynamic> json = await Api.deleteBudget(budgetId);
    if (json != null) {
      String message = 'Delete Successfully !';
      if (false == json['success']) {
        message = json['message'] ?? '';
      } else {
        cb();
      }
      Fluttertoast.showToast(
          msg: message,
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIos: 1,
          fontSize: 16.0);
    }
  }


  @action
  Future editBudget(Map<String, dynamic> formData, OnVoidSuccess cb) async {
    var json = await Api.editBudget(formData);
    if (json != null) {
      String message = 'Update Successfully !';
      if (false == json['success']) {
        message = json['message'] ?? '';
      } else {
        cb();
      }
      Fluttertoast.showToast(
          msg: message,
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIos: 1,
          fontSize: 16.0);
    }
  }
}

final budgetStore = new Budget();
